<?php
/**
 * Zend Framework (http://framework.zend.com/)
 *
 * @link      http://github.com/zendframework/ZendSkeletonApplication for the canonical source repository
 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
 * @license   http://framework.zend.com/license/new-bsd New BSD License
 */
namespace Application\Controller;

use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
use Zend\Paginator\Paginator;
use Zend\Db\Sql\Select;
use Zend\Paginator\Adapter\Iterator as paginatorIterator;
use Admin\Form\MenuForm;
use Admin\Model\Category;
use Zend\Json\Json;
use PayPalAPIInterfaceServiceService;
use PaymentDetailsType;
use PaymentDetailsItemType;
use BasicAmountType;
use SetExpressCheckoutRequestDetailsType;
use SetExpressCheckoutRequestType;
use SetExpressCheckoutReq;
use GetExpressCheckoutDetailsRequestType;
use GetExpressCheckoutDetailsReq;
use Application\Model\vn3dUtil;
use DoExpressCheckoutPaymentRequestDetailsType;
use DoExpressCheckoutPaymentRequestType;
use DoExpressCheckoutPaymentReq;
use Application\Model\Order;
use Application\Model\OrderProduct;

class StoreController extends AbstractActionController
{

    protected $CategoryTable;

    protected $ProductTable;

    protected $ImageTable;

    protected $OrderTable;

    protected $OrderProductTable;

    public function getOrderTableTable()
    {
        if (! $this->OrderTable) {
            $sm = $this->getServiceLocator();
            $this->OrderTable = $sm->get('Application\Model\OrderTable');
        }
        return $this->OrderTable;
    }

    public function getOrderProductTable()
    {
        if (! $this->OrderProductTable) {
            $sm = $this->getServiceLocator();
            $this->OrderProductTable = $sm->get('Application\Model\OrderProductTable');
        }
        return $this->OrderProductTable;
    }

    public function getCategoryTable()
    {
        if (! $this->CategoryTable) {
            $sm = $this->getServiceLocator();
            $this->CategoryTable = $sm->get('Application\Model\CategoryTable');
        }
        return $this->CategoryTable;
    }

    public function getProductTable()
    {
        if (! $this->ProductTable) {
            $sm = $this->getServiceLocator();
            $this->ProductTable = $sm->get('Application\Model\ProductTable');
        }
        return $this->ProductTable;
    }

    public function getImageTable()
    {
        if (! $this->ImageTable) {
            $sm = $this->getServiceLocator();
            $this->ImageTable = $sm->get('Application\Model\ImageTable');
        }
        return $this->ImageTable;
    }

    public function reomveItemAction()
    {
        $this->layout("layout/ajax");
        $token = $this->params()->fromRoute('id', 0);

        $this->ZendCart()->remove(array(
            'token' => $token
        ));
        echo Json::encode(array(
            "status" => 1
        ));
        return $this->getResponse();
    }

    public function searchAction()
    {
        $this->layout()->menu = $this->getCategoryTable()->getTree();
        $cart = $this->ZendCart()->cart();
        $this->layout()->cart = $cart;
        $totalItems = $this->ZendCart()->total_items();
        $this->layout()->totalItems = $totalItems;
        $totalPrice = $this->ZendCart()->total();
        $this->layout()->totalPrice = $totalPrice;
    }

    public function homeAction()
    {
        $this->forward()->dispatch("Application\Controller\Store", array(
            'action' => 'search',
            'controller' => 'Application\Controller\Store'
        ));

        return array(
            'newProduct' => $this->getProductTable()->fetchNewProduct(),
            'featuredLevels' => $this->getProductTable()->fetchNewProduct(),
            'featuredCharacters' => $this->getProductTable()->fetchNewProduct(),
            'topProduct' => $this->getProductTable()->fetchTopProduct()
        );
    }

    public function productAction()
    {
        $id = $this->params()->fromRoute('id', 0);
        $product = $this->getProductTable()->getProductbyId($id);
        $images = $this->getImageTable()->getImageByProductId($id);
        $groupProduct = $this->getCategoryTable()->getCategorybyId($product->category_id);
        $menu = $this->getCategoryTable()->getCategorybyId($groupProduct->parent_id);
        $this->forward()->dispatch("Application\Controller\Store", array(
            'action' => 'search',
            'controller' => 'Application\Controller\Store'
        ));
        return array(
            "product" => $product,
            "images" => $images,
            "groupProduct" => $groupProduct,
            "menu" => $menu
        );
    }

    public function productsAction()
    {
//         q:hhhh
//         typesearch:any
//         searchname:y
//         searchshortdesc:y
//         searchdesc:y
//         searchkeyword:y
//         searchinsubcat:n
//         searchinsubcat:n
//         category:all
//         productcode:66666
//         pricefrom:666
//         priceto:666666
//         lbsfrom:6666
//         lbsto:6666
        $q = $this->getRequest()->getQuery("q");
        $typesearch = $this->getRequest()->getQuery("typesearch");
        $searchname = $this->getRequest()->getQuery("searchname");
        $earchshortdesc = $this->getRequest()->getQuery("earchshortdesc");
        $searchdesc = $this->getRequest()->getQuery("searchdesc");
        $searchkeyword = $this->getRequest()->getQuery("searchkeyword");
        $searchinsubcat = $this->getRequest()->getQuery("searchinsubcat");
        $category = $this->getRequest()->getQuery("category");
        $productcode = $this->getRequest()->getQuery("productcode");
        $pricefrom = $this->getRequest()->getQuery("pricefrom");
        $priceto = $this->getRequest()->getQuery("priceto");
        $lbsfrom = $this->getRequest()->getQuery("lbsfrom");
        $lbsto = $this->getRequest()->getQuery("lbsto");

        $totalProduct = 0;
        $rowPerPage = 12;
        $typeView = "GRID";
        $order_by = "price";
        $order = "asc";
        $template = "application/store/products.phtml";
        $groupProductID = $this->params()->fromRoute('id', 0);
if(!empty($category)){
    $groupProductID=$category;
}
        $arrayGroupProductID = array(
            $groupProductID
        );
        $page = $this->params()->fromRoute('page') ? (int) $this->params()->fromRoute('page') : 1;
        if ($this->getRequest()->isPost()) {
            $rowPerPage = $this->getRequest()->getPost("rowperpage");
            $order_by = $this->getRequest()->getPost("order_by");
            $order = $this->getRequest()->getPost("order");
            $typeView = $this->getRequest()->getPost("typeView");
            $this->layout("layout/ajax");
            if ($typeView == "GRID") {
                $template = "application/store/products-grid.phtml";
            } elseif ($typeView == "LIST") {
                $template = "application/store/products-list.phtml";
            } elseif ($typeView == "PANEL") {
                $template = "application/store/products-panel.phtml";
            } elseif ($typeView == "TABLE") {
                $template = "application/store/products-table.phtml";
            }
        }
        if (! empty($groupProductID)) {
            $groupProductById = $this->getCategoryTable()->getGroupProduct($groupProductID);
            if (! empty($groupProductById)) {
                foreach ($groupProductById as $key => $gp) {
                    array_push($arrayGroupProductID, $gp->id);
                }
            }
        }
        if (empty($q)) {
        $paginator = $this->getProductTable()->fetchByGroupProductID($arrayGroupProductID, true, $order_by, $order);
        }
        if(!empty($typesearch)){
        $paginator = $this->getProductTable()->searchProduct(
            $arrayGroupProductID, true, $order_by, $order,$q,$typesearch,$searchname,
            $earchshortdesc,$searchdesc,
            $searchkeyword,$searchinsubcat,$productcode,$pricefrom,$priceto,$lbsfrom,$lbsto
            );
        }
        // set the current page to what has been passed in query string, or to 1 if none set
        $paginator->setCurrentPageNumber((int) $this->params()
            ->fromQuery('page', $page));
        // set the number of items per page to 10

        $paginator->setItemCountPerPage($rowPerPage);
        if (! empty($groupProductID)) {
            $groupProduct = $this->getCategoryTable()->getCategorybyId($groupProductID);
        }
        $this->forward()->dispatch("Application\Controller\Store", array(
            'action' => 'search',
            'controller' => 'Application\Controller\Store'
        ));
        // var_dump($q);
        $menu = $this->getCategoryTable()->getTree();
        $view = new ViewModel(array(
            'order_by' => $order_by,
            'order' => $order,
            'page' => $page,
            'paginator' => $paginator,
            "groupProduct" => $groupProduct,
            "groupProductID" => $groupProductID,
            "rowPerPage" => $rowPerPage,
            "typeView" => $typeView,
            "action" => "products",
            "route" => 'store',
            "totalProduct" => $totalProduct,
            "q" => $q,
            "menu"=>$menu
        ));

        $view->setTemplate($template);
        // var_dump($typeView);
        return $view;
    }

    /**
     *
     * @link http://modules.zendframework.com/vikey89/ZendCart
     * @return multitype:multitype:string number multitype:string
     */
    public function addToCartAction()
    {
        $this->layout("layout/ajax");
        $productID = $this->params()->fromRoute('id', 0);
        $product = $this->getProductTable()->getProductbyId($productID);
        $productCart = array(
            'id' => $product->id,
            'qty' => 1,
            'price' => $product->price,
            'name' => $product->name
        );
        // $this->ZendCart()->remove(array( 'token'=>"fasdf"));
        $cart = $this->ZendCart()->cart();
        $iscontain = false;
        foreach ($cart as $key => $value) {
            if ($product->id == $value["id"]) {
                $iscontain = true;
            }
        }
        if ($iscontain == false) {
            $this->ZendCart()->insert($productCart);
        }

        // return new ViewModel(array( 'items' => $this->ZendCart()->cart(), 'total_items' => $this->ZendCart()->total_items(), 'total' => $this->ZendCart()->total(), ));
        return array(
            "product" => $product
        );
    }

    public function previewCartAction()
    {
        $this->layout("layout/ajax");
        $cart = $this->ZendCart()->cart();

        $totalItems = $this->ZendCart()->total_items();

        $totalPrice = $this->ZendCart()->total();
        return array(
            "cart" => $cart,
            "totalItems" => $totalItems,
            "totalPrice" => $totalPrice
        );
    }

    public function searchResultAction()
    {
        $totalProduct = 0;
        $menu = $this->getCategoryTable()->getTree();
        $this->forward()->dispatch("Application\Controller\Store", array(
            'action' => 'search',
            'controller' => 'Application\Controller\Store'
        ));

        return array(
            "totalProduct" => $totalProduct,
            "menu"=>$menu
        );
    }

    public function cartAction()
    {
        $cart = $this->ZendCart()->cart();
        // var_dump($cart);
        $totalItems = $this->ZendCart()->total_items();

        $totalPrice = $this->ZendCart()->total();

        $this->forward()->dispatch("Application\Controller\Store", array(
            'action' => 'search',
            'controller' => 'Application\Controller\Store'
        ));
        return array(
            "cart" => $cart,
            "totalItems" => $totalItems,
            "totalPrice" => $totalPrice
        );
    }

    public function resetCartAction()
    {
        $this->ZendCart()->destroy();
        $this->redirect()->toRoute("store", array(
            "action" => "cart"
        ));
    }

    public function checkoutAction()
    {
        $config = vn3dUtil::getPaypalConfig();
        $paypalService = new PayPalAPIInterfaceServiceService($config);
        $setECReqDetails = new SetExpressCheckoutRequestDetailsType();

        $vn3dOrderTotal = 0;
        $cart = $this->ZendCart()->cart();
        // for
        $k = 0;
        foreach ($cart as $key => $po) {

            $itemDetails = new PaymentDetailsItemType();
            $itemDetails->Name = $po['name'];
            $itemAmount = $po['price'];
            $itemDetails->Amount = $itemAmount;
            // $itemQuantity = $po['qty'];
            $itemQuantity = '1';
            $itemDetails->Quantity = $itemQuantity;

            // add one product
            $paymentDetails = new PaymentDetailsType();

            $paymentDetails->PaymentDetailsItem[$k] = $itemDetails;

            // set total
            $orderTotal = new BasicAmountType();
            $orderTotal->currencyID = 'USD';
            $vn3dOrderTotal = $vn3dOrderTotal + $itemAmount * $itemQuantity;
            $orderTotal->value = $itemAmount * $itemQuantity;
            $paymentDetails->OrderTotal = $orderTotal;

            $paymentDetails->PaymentAction = 'Sale';
            $setECReqDetails->PaymentDetails[$k] = $paymentDetails;

            // end for
            $k ++;
        }

        //
        $setECReqDetails->CancelURL = vn3dUtil::DOMAIN;
        $setECReqDetails->ReturnURL = vn3dUtil::DOMAIN . "/store/checkout-detail";

        $setECReqType = new SetExpressCheckoutRequestType();
        $setECReqType->Version = '104.0';
        $setECReqType->SetExpressCheckoutRequestDetails = $setECReqDetails;

        $setECReq = new SetExpressCheckoutReq();
        $setECReq->SetExpressCheckoutRequest = $setECReqType;

        // var_dump($setECReq);

        $setECResponse = $paypalService->SetExpressCheckout($setECReq);
        // var_dump($setECResponse->Token);
        // var_dump($setECResponse);
        if ($setECResponse->Ack == "Success") {
            if ($config["mode"] == "sandbox") {
                $this->redirect()->toUrl("https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=" . $setECResponse->Token);
            } else {
                $this->redirect()->toUrl("https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=" . $setECResponse->Token);
            }
        } else {
            echo $setECResponse->Errors->LongMessage;
        }
        // https://www.paypal.com/vn/cgi-bin/merchantpaymentweb?cmd=_express-checkout&token=EC-4G645488S4057933G
        // https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=EC-4G645488S4057933G
    }
    // ?token=EC-63S31331TS060673D&PayerID=5VL4XU6VZR6X8
    public function checkoutDetailAction()
    {
        $cart = $this->ZendCart()->cart();
        $token = $this->getRequest()->getQuery("token");
        $payerID = $this->getRequest()->getQuery("PayerID");
        $config = vn3dUtil::getPaypalConfig();
        $paypalService = new PayPalAPIInterfaceServiceService($config);
        $getExpressCheckoutDetailsRequest = new GetExpressCheckoutDetailsRequestType($token);
        $getExpressCheckoutDetailsRequest->Version = '104.0';
        $getExpressCheckoutReq = new GetExpressCheckoutDetailsReq();
        $getExpressCheckoutReq->GetExpressCheckoutDetailsRequest = $getExpressCheckoutDetailsRequest;

        $getECResponse = $paypalService->GetExpressCheckoutDetails($getExpressCheckoutReq);
        $securityCode = md5($token . "**" . $payerID . "**" . $getECResponse->Timestamp);
        // var_dump($getECResponse);
        $order = new Order();
        $oldOrder = $this->getOrderTableTable()->getOrderbyTokenPayerid($token, $payerID);
        if (! empty($oldOrder)) {
            $order->id = $oldOrder->id;
        }

        $order->ack = $getECResponse->Ack;
        $order->address = $getECResponse->GetExpressCheckoutDetailsResponseDetails->BillingAddress->Name;
        $order->city = $getECResponse->GetExpressCheckoutDetailsResponseDetails->BillingAddress->CityName;
        $order->country = $getECResponse->GetExpressCheckoutDetailsResponseDetails->BillingAddress->CountryName;
        $order->email_address = $getECResponse->GetExpressCheckoutDetailsResponseDetails->PayerInfo->Payer;
        $order->first_name = $getECResponse->GetExpressCheckoutDetailsResponseDetails->PayerInfo->PayerName->FirstName;
        $order->last_name = $getECResponse->GetExpressCheckoutDetailsResponseDetails->PayerInfo->PayerName->LastName;

        $order->payerid = $getECResponse->GetExpressCheckoutDetailsResponseDetails->PayerInfo->PayerID;
        $order->payerstatus = $getECResponse->GetExpressCheckoutDetailsResponseDetails->PayerInfo->PayerStatus;
        $order->phone = $getECResponse->GetExpressCheckoutDetailsResponseDetails->PayerInfo->ContactPhone;
        $order->status = "CHO THANH TOAN";
        $order->token = $token;
        $order->total_price = $this->ZendCart()->total()['sub-total'];
        // $order->date_updated=$getECResponse->Timestamp;
        $order->zip_code = $getECResponse->GetExpressCheckoutDetailsResponseDetails->BillingAddress->PostalCode;
        $order->security_code = $securityCode;
        $newOrderId = $this->getOrderTableTable()->saveOrder($order);

        // for
        foreach ($cart as $key => $po) {

            $orderproduct = new OrderProduct();
            $orderproduct->order_id = $newOrderId;
            $orderproduct->price = $po['price'];
            $orderproduct->total_item = 1;
            $orderproduct->product_id = $po['id'];
            $orderproduct->security_code = $securityCode;
            $orderproduct->total_download = 0;
            $this->getOrderProductTable()->saveOrderProduct($orderproduct);
        }

        if ($getECResponse->GetExpressCheckoutDetailsResponseDetails->PayerInfo->PayerStatus == 'verified' && $getECResponse->Ack == "Success") {

            $DoECRequestDetails = new DoExpressCheckoutPaymentRequestDetailsType();
            $DoECRequestDetails->PayerID = $payerID;
            $DoECRequestDetails->Token = $token;

            $paypalService = new PayPalAPIInterfaceServiceService($config);

            // $paymentDetails->PaymentAction = 'Sale';
            // $paymentDetails->NotifyURL = vn3dUtil::DOMAIN;

            // add product
            $paymentDetails = new PaymentDetailsType();

            $cart = $this->ZendCart()->cart();
            // for
            $k = 0;
            foreach ($cart as $key => $po) {

                $itemDetails = new PaymentDetailsItemType();
                $itemDetails->Name = $po['name'];
                $itemAmount = $po['price'];
                $itemDetails->Amount = $itemAmount;
                $itemQuantity = $po['qty'];
                $itemDetails->Quantity = $itemQuantity;

                // add one product
                $paymentDetails->PaymentDetailsItem[$k] = $itemDetails;

                // set total
                $orderTotal = new BasicAmountType();
                $orderTotal->currencyID = 'USD';
                $orderTotal->value = $itemAmount * $itemQuantity;
                $paymentDetails->OrderTotal = $orderTotal;

                $paymentDetails->PaymentAction = 'Sale';
                $DoECRequestDetails->PaymentDetails[$k] = $paymentDetails;
                // $DoECRequestDetails->PaymentDetails[$k] = $paymentDetails;
                // end for
                $k ++;
            }
            //

            $DoECRequest = new DoExpressCheckoutPaymentRequestType();
            $DoECRequest->DoExpressCheckoutPaymentRequestDetails = $DoECRequestDetails;
            $DoECRequest->Version = '104.0';

            $DoECReq = new DoExpressCheckoutPaymentReq();
            $DoECReq->DoExpressCheckoutPaymentRequest = $DoECRequest;

            $DoECResponse = $paypalService->DoExpressCheckoutPayment($DoECReq);

            // var_dump($DoECResponse);
            $isSuccess = false;
            if ($DoECResponse->Ack == "Success") {
                $this->ZendCart()->destroy();
                $isSuccess = true;
                $order->id = $newOrderId;
                $order->status = "DA THANH TOAN";
                $this->getOrderTableTable()->saveOrder($order);
            } else {
                $isSuccess = false;
            }

            if ($isSuccess) {

                $this->redirect()->toUrl(vn3dUtil::DOMAIN . "/store/download-product?securitycode=" . $securityCode);
            }
        } else {
            echo $getECResponse->Errors->LongMessage;
        }
        // store order and order detail, generate security key for order
    }

    public function downloadProductAction()
    {
        $securitycode = $this->getRequest()->getQuery("securitycode");

        $isSuccess = false;

        // $order=$this->getOrderTableTable()->getOrderbyTokenPayerid($token, $payerID);
        $order = $this->getOrderTableTable()->getOrderbySecurityCode($securitycode);
        if ($order->status == "DA THANH TOAN") {
            $isSuccess = true;
        }
        $arrayProductId = $this->getOrderProductTable()->getArrayProductByOrderId($order->id);
        // var_dump($arrayProductId);
        $cart = $this->getProductTable()->getProductbyArrayId($arrayProductId);
        $this->forward()->dispatch("Application\Controller\Store", array(
            'action' => 'search',
            'controller' => 'Application\Controller\Store'
        ));
        return array(
            "cart" => $cart,
            "isSuccess" => $isSuccess,
            "order" => $order
        );
    }

    public function bannerAction()
    {
        $id = (int) $this->params()->fromRoute('id', 0);
        $image = $this->getProductTable()->getProductbyId($id);

        $imageFile = $image->banner;
        $contentType = $image->banner_type;
        header("Expires: Sat, 18 Jul 2015 05:00:00 GMT");
        header("Cache-Control: max-age=6000");
        header('Content-type: ' . $contentType . ';');
        echo $imageFile;
        return $this->getResponse();
    }

    public function imageAction()
    {
        $id = (int) $this->params()->fromRoute('id', 0);
        $image = $this->getImageTable()->getImagebyId($id);

        $imageFile = $image->content;
        $contentType = $image->type;
        header("Expires: Sat, 18 Jul 2015 05:00:00 GMT");
        header("Cache-Control: max-age=6000");
        header('Content-type: ' . $contentType . ';');
        echo $imageFile;
        return $this->getResponse();
    }

    public function downloadAction()
    {
        $productId = (int) $this->params()->fromRoute('id', 0);
        $securitycode = $this->getRequest()->getQuery("securitycode");

        $orderProduct = $this->getOrderProductTable()->getOrderProductBySecurityCode($securitycode, $productId);

        $id = (int) $orderProduct->product_id;
        $product = $this->getProductTable()->getProductbyId($id);
        $error = "";
        if (empty($product)) {

            $error = "Error!";
            return array(
                "error" => $error,
                "securitycode" => $securitycode
            );
        } elseif ($orderProduct->total_download > vn3dUtil::TOTAL_DOWNLOAD) {

            $error = "Too manny download!";
            return array(
                "error" => $error,
                "securitycode" => $securitycode
            );
        } else {
            $orderProduct->total_download = 1 + $orderProduct->total_download;
            $this->getOrderProductTable()->saveOrderProduct($orderProduct);
            $productFile = $product->product_file;
            $contentType = $product->product_file_type;
            $sizeFile = $product->product_file_size;
            $nameFile = $product->product_file_name;

            header("Pragma: public");
            header("Expires: 0");
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Content-Type: application/force-download");
            header("Content-Type: application/octet-stream");
            header("Content-Type: application/download");
            header("Content-Disposition: attachment;filename=" . $nameFile);
            header("Content-Transfer-Encoding: binary ");

            header("Content-Length: " . $sizeFile);
            header('Content-type: ' . $contentType . ';');
            echo $productFile;
            return $this->getResponse();
        }
    }
}
